/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

class GlobalConfig {

    public static final int BASE_VALUE = 1000;
    public static final int DECIMALISM_256 = 0x100;
    public static final int LOOP_I_MAX_350 = 350;
    public static final int LOOP_Y_MAX_256 = 256;
    public static final int EXECUTION_MAX_80 = 80;

    public static boolean inDebug = false;
    public static void log(String str) {
        if (inDebug) {
            System.out.println(str);
        }
    }
    public static double currentTimestamp13() {
        return (double) System.nanoTime() / 1_000_000;
    }

    // 1 op = 2 assigns, 16 compare/branches, 8 ANDs, (0-8) ADDs, 8 SHLs
// O(n)
    public static int bitSinByte(int b) {
        int m = 1;
        int c = 0;
        while (m < DECIMALISM_256) {
            if ((b & m) != 0) {
                c += 1;
            }
            m <<= 1;
        }
        return c;
    }

    public static int timeFunc() {
        int sum = 0;
        for (int i = 0; i < LOOP_I_MAX_350; i++) {
            for (int y = 0; y < LOOP_Y_MAX_256; y++) {
                sum += bitSinByte(y);
            }
        }
        return sum;
    }
}
/*
 * @State
 * @Tags Jetstream2
 */
class Benchmark {
    /*
     * @Benchmark
     */
    public void run() {
        int result = GlobalConfig.timeFunc();
        int expected = 358400;
        if (result != expected) {
            throw new Error("ERROR: bad result: expected " + expected + " but got " + result);
        }
    }

    public static void main(String[] args) {
        double startTime = GlobalConfig.currentTimestamp13();
        Benchmark benchmark = new Benchmark();
        for (int i = 0; i < GlobalConfig.EXECUTION_MAX_80; i++) {
            double startTimeInLoop = GlobalConfig.currentTimestamp13();
            benchmark.run();
            double endTimeInLoop = GlobalConfig.currentTimestamp13();
            //GlobalConfig.log("bitops_bits_in_byte: ms = " +  (endTimeInLoop - startTimeInLoop) + " i= " + i)
        }
        double endTime = GlobalConfig.currentTimestamp13();
        System.out.println("bitops-bits-in-byte: ms = " + (endTime - startTime));
    }
}
